<script>
  import Select from './select'
  import Option from './option.vue'

  export default {
    name: 'SelectMultiple',
    components: {
      Select,
      Option
    },
    model: {
      prop: 'value',
      event: 'change'
    },
    props: {
      value: {
        type: Array,
        default: () => []
      },
      options: {
        type: [Array, Function],
        default: () => []
      },
      optionsAllFormatter: {
        type: String,
        default: '全部'
      },
      optionsValueFormatter: {
        type: Function,
        default: item => item.value || ''
      },
      optionsLabelFormatter: {
        type: Function,
        default: item => item.label || ''
      },
      // 是否输入框中显示全部选项
      isInputShowAllOption: {
        type: Boolean,
        default: false
      },
      placeholder: {
        type: String,
        default: '请选择'
      },
      collapseTags: {
        type: Boolean,
        default: true
      }
    },
    data() {
      return {
        val: this.value,
        allValue: 'all', // 全部选项 value
        oldOptions: [[]] // 用来储存上一次的数据
      }
    },
    computed: {
      opts() {
        const options = (typeof this.options === 'function' ? this.options() : this.options)
          .map(item => ({
            value: this.optionsValueFormatter(item),
            label: this.optionsLabelFormatter(item)
          }))
        return [{
          value: this.allValue,
          label: this.optionsAllFormatter
        }].concat(options)
      }
    },
    watch: {
      value(newValue) {
        this.val = newValue
      },
      val(newValue) {
        this.$emit('change', newValue)
      }
    },
    methods: {
      selectAll(val) {
        const allValues = []
        // 保留所有值
        for (const item of this.opts) {
          allValues.push(item.value)
        }

        // 用来储存上一次的值，可以进行对比
        const oldVal = this.oldOptions.length === 1 ? [] : this.oldOptions[1]

        // 若是全部选择
        if (val.includes(this.allValue)) this.val = allValues

        // 取消全部选中  上次有 当前没有 表示取消全选
        if (oldVal.includes(this.allValue) && !val.includes(this.allValue)) this.val = []

        // 点击非全部选中  需要排除全部选中 以及 当前点击的选项
        // 新老数据都有全部选中
        if (oldVal.includes(this.allValue) && val.includes(this.allValue)) {
          const index = val.indexOf(this.allValue)
          val.splice(index, 1) // 排除全选选项
          this.val = val
        }

        // 全选未选 但是其他选项全部选上 则全选选上 上次和当前 都没有全选
        if (!oldVal.includes(this.allValue) && !val.includes(this.allValue)) {
          if (val.length === allValues.length - 1) this.val = [this.allValue].concat(val)
        }

        // 储存当前最后的结果 作为下次的老数据
        this.oldOptions[1] = this.val
      }
    },
    render() {
      return (
        <Select
          v-model={ this.val }
          multiple={ true }
          collapse-tags={ this.collapseTags }
          on-change={ this.selectAll }
          selectedFilterFn={ this.isInputShowAllOption ? () => true : item => item.value !== this.allValue }
        >
          {
            this._l(this.opts, item => (
              <Option
                key={ item.value }
                label={ item.label }
                value={ item.value }/>
            ))
          }
        </Select>
      )
    }
  }
</script>

